#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

#include <assert.h>

static lua_State * L = 0;

int load_server_config(const char * config)
{
	lua_State * new_L = luaL_newstate();
	if (new_L == 0) {
		return -1;
	}
	luaL_openlibs(new_L);
	if (luaL_dofile(new_L, config) != 0) {
		lua_close(new_L);
		return -1;
	}

	if (L) {
		lua_close(L);
	}

	L = new_L;
	return 0;
}

const char * read_config_string(const char * key, ...)
{
	if (L == 0 || key == 0) {
		return 0;
	}

	int old_top = lua_gettop(L);

	lua_getglobal(L, key);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		return 0;
	}

	const char * ret = 0;

	int stack = 1;
	va_list args;
	va_start(args, key);
	while(1) {
		const char * xkey = va_arg(args, const char *);
		if (xkey == 0) {
			if (lua_isnumber(L, -1) || lua_tostring(L, -1)) {
				ret = lua_tostring(L, -1);
			}
			break;
		}

		if (!lua_istable(L, -1)) {
			break;
		}

		lua_pushstring(L, xkey);
		lua_gettable(L, -2);
		stack++;
	};
	va_end(args);
	lua_pop(L, stack);

	assert(lua_gettop(L) == old_top);
	return ret;
}

int read_config_int(const char * key, ...)
{
	if (L == 0 || key == 0) {
		return 0;
	}

	int old_top = lua_gettop(L);

	lua_getglobal(L, key);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		return 0;
	}

	int ret = 0;

	int stack = 1;
	va_list args;
	va_start(args, key);
	while(1) {
		const char * xkey = va_arg(args, const char *);
		if (xkey == 0) {
			if (lua_isnumber(L, -1)) {
				ret = lua_tointeger(L, -1);
			}
			break;
		}

		if (!lua_istable(L, -1)) {
			break;
		}

		lua_pushstring(L, xkey);
		lua_gettable(L, -2);
		stack++;
	};
	va_end(args);
	lua_pop(L, stack);

	assert(lua_gettop(L) == old_top);
	return ret;
}
